package com.ujoku.controller;

import com.labillusion.core.platform.exception.LoginRequiredException;
import com.labillusion.core.platform.exception.ResourceNotFoundException;
import com.labillusion.core.platform.web.pagination.PaginationForm;
import com.labillusion.core.platform.web.rest.RESTController;
import com.labillusion.core.platform.web.rest.exception.InvalidRequestException;
import com.labillusion.core.platform.web.security.HTMLInputFilter;
import com.labillusion.core.util.MessageSourceUtils;
import com.labillusion.core.util.SequenceNumUtils;
import com.labillusion.core.util.StringUtils;
import com.labillusion.core.util.UUIDUtils;
import com.ujoku.context.ActionContext;
import com.ujoku.domain.*;
import com.ujoku.interceptor.LoginRequired;
import com.ujoku.request.OrderHistoryForm;
import com.ujoku.request.ReviewForm;
import com.ujoku.service.*;
import com.ujoku.view.builder.OrderViewBuilder;
import com.ujoku.view.domain.OrderListView;
import com.ujoku.view.domain.SalesRecordView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Andy.Lian on 2014/11/1.
 */
@RestController
public class OrderController extends RESTController {

    private static Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    protected CartService cartService;
    @Autowired
    protected AddressService addressService;
    @Autowired
    protected ShippingService shippingService;
    @Autowired
    protected MessageSourceUtils messageSourceUtils;
    @Autowired
    protected OrderService orderService;

    @Autowired
    protected OrderItemService orderItemService;
    @Autowired
    protected RegionService regionService;
    @Autowired
    protected OrderViewBuilder orderViewBuilder;
    @Autowired
    private MyListItemService myListItemService;
    @Autowired
    private GoodsSpecService goodsSpecService;
    @Autowired
    private ActionContext actionContext;
    @Autowired
    private ReviewService reviewService;

    @Autowired
    private HTMLInputFilter htmlInputFilter;

    @RequestMapping(value="/order/placeOrder", method = RequestMethod.GET)
    @ResponseBody
    @LoginRequired
    public Order PlaceOrder(){

        Cart cart = actionContext.getCart();
        if(cart==null || cart.getCartItemList().size()<=0)
            throw new InvalidRequestException(messageSourceUtils.getMessage("cart.not.found"));

        //validate order form address
        if(cart.getShippingAddress()==null){
            throw new InvalidRequestException("address","发货地址不能为空!");
        }
        Member member = actionContext.getMember();

        for(CartItem cartItem : cart.getCartItemList()) {
            goodsSpecService.checkInventory(cartItem);

            if (!StringUtils.hasText(cartItem.getMyListItemId())) {
                continue;
            }
            MyListItem myListItem = (MyListItem) myListItemService.selectById(cartItem.getMyListItemId());
            if (!myListItem.getOnSale() || myListItem.getMemberId() == member.getUser_id()) {
                actionContext.setCart(null);
                throw new InvalidRequestException("legacyCart", myListItem.getGoodsName() + "商品已下架.");
            }
        }

        Address address = cart.getShippingAddress();
        //build order
        Order order = new Order();
        order.setId(SequenceNumUtils.generateNum());
        order.setCartId(cart.getId());
        order.setMemberId(cart.getMemberId());
        order.setContact(address.getContact());
        order.setCity(address.getCity());
        order.setProvince(address.getProvince());
        order.setCounty(address.getCounty());
        order.setPhone(address.getPhone());
        order.setShippingAddress(address.getShippingAddress());
        order.setZipCode(address.getZipCode());
        order.setDeliveryType(cart.getDeliveryType());
        order.setLevel(cart.getLevel());
        order.setDiscount(cart.getDiscount());
        order.setDiscountPercent(cart.getDiscountPercent());
        order.setShippingFee(cart.getShippingFee());
        order.setSubTotal(cart.getSubTotal());
        order.setTotal(cart.getTotal());
        order.setOrderItemList(new ArrayList<>());

        Store store = cart.getStore();
        if(store != null){
            order.setStoreId(store.getId());
        }

        for(CartItem item : cart.getCartItemList()){
            OrderItem orderItem = new OrderItem();
            orderItem.setId(UUIDUtils.random());
            orderItem.setCartItemId(item.getId());
            orderItem.setOrderId(order.getId());
            orderItem.setGoodsId(item.getGoodsId());
            orderItem.setGoodsName(item.getGoodsName());
            orderItem.setQty(item.getQty());
            orderItem.setPrice(item.getPrice());
            orderItem.setGoodsPrice(item.getGoodsPrice());
            orderItem.setMyListItemId(item.getMyListItemId());
            order.getOrderItemList().add(orderItem);
            orderItemService.insert(orderItem);
        }

        orderService.insert(order);

        orderService.setGoodsSaleCount(order);
        orderService.setMyListItemSaleCount(order);

        cartService.deleteById(cart.getId());
        actionContext.setCart(null);

        return order;
    }

    @RequestMapping(value="/orderHistory", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public OrderListView getOrderList(@RequestBody @Valid OrderHistoryForm form) throws Exception{
        Member member = actionContext.getMember();
        Map<String,Object> query = form.getQueryMap();
        query.put("memberId", member.getUser_id());
        if(form.getStatus() != 0)
            query.put("status",form.getStatus());

        if(StringUtils.hasText(form.getProductName()))
            query.put("productName","%" + form.getProductName() + "%");


        List<Order> orders = orderService.selectList(query);
        int count = orderService.selectCount(query);
        if (orders==null || orders.size()<=0)
            throw new ResourceNotFoundException(messageSourceUtils.getMessage("order.not.found"));

        OrderListView orderListView = new OrderListView();

        orderListView.setOrderList(orders);
        orderListView.setCount(count);

        Map<String,Integer> countQuery = new HashMap<>();
        countQuery.put("memberId", member.getUser_id());
        int[] counts = new int[4];
        for(int i = 1;i <= 4 ;i ++){
            countQuery.put("status", i);
            counts[i-1] = orderService.selectCount(countQuery);
        }

        orderListView.setCountUnPay(counts[0]);
        orderListView.setCountUnDel(counts[1]);
        orderListView.setCountUnCon(counts[2]);
        orderListView.setCountUnEva(counts[3]);

        return orderListView;
    }

    @RequestMapping(value="/order/{id}", method = RequestMethod.GET)
    @ResponseBody
    @LoginRequired
    public Order orderDetail(@PathVariable String id){
        Member member = actionContext.getMember();
        Order order = orderService.selectById(id, member.getUser_id());

        return order;
    }

    @RequestMapping(value="/orderStatus/{id}", method = RequestMethod.GET)
    @ResponseBody
    @LoginRequired
    public int orderStatus(@PathVariable String id){
        Member member = actionContext.getMember();
        int orderStatus = orderService.selectOrderStatusById(id, member.getUser_id());

        return orderStatus;
    }

    @RequestMapping(value="/orderConfirm/{id}", method = RequestMethod.PUT)
    @ResponseBody
    @LoginRequired
    public String orderConfirm(@PathVariable String id){
        Member member = actionContext.getMember();
        Order order = orderService.selectById(id, member.getUser_id());
        if(order.getStatus() != OrderStatus.Shipped)
            throw new InvalidRequestException("order status invalid");

        order.setStatus(OrderStatus.Confirmed);
        orderService.update(order);

        return "successfully";
    }

    @RequestMapping(value="/order/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    @LoginRequired
    public Order orderCancel(@PathVariable String id){
        Member member = actionContext.getMember();
        Order order = orderService.selectById(id, member.getUser_id());
        if(order.getStatus() != OrderStatus.Created)
            throw new InvalidRequestException("order stats invalid");

        orderService.rollBackGoodsSaleCount(order);
        orderService.rollBackMyListItemSaleCount(order);

        order.setStatus(OrderStatus.Cancel);
        orderService.update(order);

        return order;
    }

    @RequestMapping(value="/orderReview/add", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public String orderEvaluateAdd(@Valid @RequestBody ReviewForm form){
        Member member = actionContext.getMember();
        Order order = orderService.selectById(form.getOrder_id(), member.getUser_id());
        if(order.getStatus() != OrderStatus.Confirmed)
            throw new InvalidRequestException("order status invalid");

        for (int i = 0; i < form.getReviews().size(); i++) {
            if(!StringUtils.hasText(form.getReviews().get(i).getGoods_review())) continue;
            Review review = form.getReviews().get(i);

            //对评论内容进行防XSS处理
            String input = htmlInputFilter.filter(review.getGoods_review());
            review.setGoods_review(input);

            review.setId(SequenceNumUtils.generateNum());
            reviewService.insert(review);
        }

        order.setStatus(OrderStatus.Finished);
        orderService.update(order);

        return "successfully";
    }

    @RequestMapping(value="/salesRecord", method = RequestMethod.POST)
    @ResponseBody
    @LoginRequired
    public SalesRecordView salesRecordList(@RequestBody @Valid PaginationForm form) throws Exception{
        Member member = actionContext.getMember();
        if(member==null){
            throw new LoginRequiredException(messageSourceUtils.getMessage("session.login.required"));
        }

        Map<String,Object> query = new HashMap<>();
        query.put("memberId",member.getUser_id());

        int count = orderItemService.selectSalesCount(query);
        member.setSalesCount(count);
        actionContext.setMember(member);

        query = form.getQueryMap();
        query.put("memberId",member.getUser_id());

        List<OrderItem> orderItemList = orderItemService.selectCellarSellRecord(query);

        SalesRecordView salesRecordView = new SalesRecordView();
        salesRecordView.setCount(count);
        salesRecordView.setSalesRecordList(orderItemList);

        return salesRecordView;
    }
}
